//! @Author: DengLibin 榆霖
//! @Date:  2022-06-30 16:18:33
//! @Description: 


use std::collections::HashMap;

use common::date;
use mysql::{TxOpts, prelude::Queryable, params};

use crate::{entity::user::User, pojo::PageInfo};


/// @Author: DengLibin 榆霖
/// @Date:  2022-06-30 16:59:54
/// @Description: 添加
pub  fn insert(u: &User, pool: &mysql::Pool) -> Result<bool, Box<dyn std::error::Error>>{
    let mut conn = pool.get_conn()?;
    let mut tx = conn.start_transaction(TxOpts::default())?;
    let image_url = match &u.image_url {
        Some(url) => url.as_str(),
        None=> "",
    };

    tx.exec_drop("INSERT INTO user (id,deleted,create_time,
        update_time,create_by,update_by,
        user_login_name, name, phone_num, 
        passwords, image_url) 
        VALUES (?,?,?,?,?, ?,?,?,?,?, ?)", 
          (u.id, false, date::get_chrono_local_now_time_str(),
            date::get_chrono_local_now_time_str(), u.create_by, u.update_by,
            u.user_login_name.as_str(), u.name.as_str(), 
            u.phone_num.as_str(), u.passwords.as_str(), image_url

        ))?;
    tx.commit()?;
    return Ok(true)
}
/// @Author: DengLibin 榆霖
/// @Date:  2022-07-01 13:39:11
/// @Description: 批量添加
pub fn insert_batch(users: &Vec<User>, pool: &mysql::Pool)-> Result<u64, Box<dyn std::error::Error>> {

    let mut conn = pool.get_conn()?;
    conn.exec_batch(
        r"INSERT INTO user (id,deleted,create_time,
            update_time,create_by,update_by,
            user_login_name, name, phone_num, 
            passwords, image_url)
          VALUES (:id, :deleted, :create_time,
            :update_time, :create_by, :update_by,
            :user_login_name, :name, :phone_num, 
            :passwords, :image_url)",
            users.iter().map(|u| params! {
            "id" => u.id,
            "deleted" => u.deleted,
            "create_time" => date::get_chrono_local_now_time_str(),
            "update_time" => date::get_chrono_local_now_time_str(),
            "create_by" => u.create_by,
            "update_by" => u.update_by,
            "user_login_name" => u.user_login_name.as_str(),
            "name" => u.name.as_str(),
            "phone_num" => u.phone_num.as_str(),
            "passwords" => u.passwords.as_str(),
            "image_url" => {
                match &u.image_url {
                    Some(url) => url.as_str(),
                    None=> "",
                }
            },
        })
    )?;
    let affect_row = conn.affected_rows();
    drop(conn);
    return Ok(affect_row);
}

/// @Author: DengLibin 榆霖
/// @Date:  2022-07-01 13:53:32
/// @Description: 查询所有
pub fn get_all(pool: &mysql::Pool) -> Result<Vec<User>, Box<dyn std::error::Error>> {
    let mut conn = pool.get_conn()?;
    let users = conn
    .query_map(
        "SELECT id,deleted,create_time,
        update_time,create_by,update_by,
        user_login_name, name, phone_num, 
        passwords, image_url FROM user",
        |(id,deleted,create_time,
            update_time,create_by,update_by,
            user_login_name, name, phone_num, 
            passwords, image_url)| {
                User { id,deleted,create_time,
                    update_time,create_by,update_by,
                    user_login_name, name, phone_num, 
                    passwords, image_url }
        },
    )?;
    return Ok(users);
}


/// @Author: DengLibin 榆霖
/// @Date:  2022-07-05 09:56:49
/// @Description: 分页查询
pub fn get_page(page: i32, size: i32, pool: &mysql::Pool) -> Result<PageInfo<User>, Box<dyn std::error::Error>>{
    let mut conn = pool.get_conn()?;
    let sql_list = "SELECT id,deleted,create_time,
    update_time,create_by,update_by,
    user_login_name, name, phone_num, 
    passwords, image_url FROM user";

    //查询总数
    let sql_total = format!("SELECT COUNT(1) FROM ({}) t", sql_list);
    //分页
    let sql_page = format!("{} LIMIT {} OFFSET  {}", sql_list, size, (page -1) * size);

    //列表
    let users = conn
    .query_map(
        sql_page,
        |(id,deleted,create_time,
            update_time,create_by,update_by,
            user_login_name, name, phone_num, 
            passwords, image_url)| {
                User { id,deleted,create_time,
                    update_time,create_by,update_by,
                    user_login_name, name, phone_num, 
                    passwords, image_url }
        },
    )?;
    //总数
    let r = conn.query_first::<i32, &str>(sql_total.as_str());
    let total = match r {
        Ok(o) => match  o {
            Some(t) => t,
            None => 0,
        },
        Err(e) => {
            error!("get_page--------------------::{}", e);
            0
        },
    };

    return Ok(PageInfo{page: page, size: size, total, list: users});
    
}

/// @Author: DengLibin 榆霖
/// @Date:  2022-07-05 10:06:56
/// @Description: 删除
pub fn delete(id: i64, pool: &mysql::Pool) -> Result<bool, Box<dyn std::error::Error>>{
    let delete_sql = "DELETE FROM user where id = ?";

    let mut conn = pool.get_conn()?;
    let mut tx = conn.start_transaction(TxOpts::default())?;
    tx.exec_drop(delete_sql, 
          (id,))?;
    tx.commit()?;
    return Ok(true)
}
/// @Author: DengLibin 榆霖
/// @Date:  2022-07-05 10:17:46
/// @Description: 更新
pub fn update(map: HashMap<&str, &str>, id: i64, pool: &mysql::Pool)-> Result<bool, Box<dyn std::error::Error>> {
    let mut update_sql = String::from("UPDATE user SET ");
    let size = map.len();
    let mut index = 0;
    //保存参数
    let mut values: Vec<&str>= vec![];
      //遍历
      for (k, v) in map {
        update_sql.push_str(k);
        update_sql.push_str("=");
        update_sql.push_str("?");
        //参数
        values.insert(index, v);
        index += 1;
        if index < size {
            update_sql.push(',');
        }
    }
    update_sql.push_str(" WHERE ID = ?");
    let str_id = format!("{}", id);
    //id
    values.insert(index, &str_id);

    let mut conn = pool.get_conn()?;
    let mut tx = conn.start_transaction(TxOpts::default())?;
    //执行更新
    tx.exec_drop(update_sql.as_str(), 
          values)?;
    tx.commit()?;
    return Ok(true);
}